﻿using FFSupplier.Model;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;

namespace FFSupplier.Common.Helper
{
    public class CommonHelper
    {
        public OrganizationServiceProxy _service;
        public CommonHelper()
        {
            MSCRMHELPER ser = new MSCRMHELPER();
            _service = ser.CrmService;
        }
        #region 实体转换Model
        public List<T> EntityToModel<T>(EntityCollection entitys)
        {
            Type t = typeof(T);
            List<T> list = new List<T>();
            //循环从CRM读取的记录
            for (int i = 0; i < entitys.Entities.Count; i++)
            {
                //创建实例
                var obj = Activator.CreateInstance(t);
                //循环实体的每个字段
                foreach (var propertyItem in t.GetProperties())
                {
                    //为查找名称赋值
                    if (propertyItem.GetCustomAttributesData().Count > 0 && propertyItem.GetCustomAttributesData().First().ConstructorArguments.First().Value.ToString() == "lookup" && entitys.Entities[i].GetAttributeValue<EntityReference>($"{propertyItem.Name}Name") != null)
                    {
                        string value = entitys.Entities[i].GetAttributeValue<EntityReference>($"{propertyItem.Name}Name").ToString();
                        t.GetProperty($"{propertyItem.Name}").SetValue(obj, value);
                    }
                    //赋值选项集逻辑
                    else if (propertyItem.GetCustomAttributesData().Count > 0 && entitys.Entities[i].GetAttributeValue<object>($"{propertyItem.Name}") != null && propertyItem.GetCustomAttributesData().First().ConstructorArguments.First().Value.ToString() == "option")
                    {
                        //item.GetCustomAttributesData().First().ConstructorArguments.First().Value.ToString();
                        string value = entitys.Entities[i].GetAttributeValue<OptionSetValue>($"{propertyItem.Name}").GetHashCode().ToString();
                        //设置选项集值
                        t.GetProperty($"{propertyItem.Name.ToLower()}").SetValue(obj, value);
                        //获取选相集
                        var PickListModellist = RetrievePicklistFromSpecified(t.Name, propertyItem.Name.ToLower());
                        //设置选相集Name
                        foreach (var plist in PickListModellist)
                        {
                            if (plist.AttributeValue.ToString() == value)
                            {
                                t.GetProperty($"{propertyItem.Name.ToLower()}Name").SetValue(obj, plist.Value);
                                break;
                            }
                        }
                    }
                    //为查找Value赋值
                    else if (propertyItem.GetCustomAttributesData().Count > 0 && propertyItem.GetCustomAttributesData().First().ConstructorArguments.First().Value.ToString() == "Guid" && entitys.Entities[i].GetAttributeValue<EntityReference>($"{propertyItem.Name}") != null)
                    {
                        propertyItem.SetValue(obj, new Guid(entitys.Entities[i].GetAttributeValue<EntityReference>($"{propertyItem.Name}").Id.ToString()));
                    }
                    //普通字段赋值
                    else if (entitys.Entities[i].Contains($"{propertyItem.Name.ToLower()}"))
                    {
                        propertyItem.SetValue(obj, entitys.Entities[i].Attributes[$"{propertyItem.Name.ToLower()}"]);
                    }
                }
                list.Add((T)obj);
            }
            return list;
        }

        #endregion

        /// <summary>
        /// 获得选项集的信息
        /// </summary>
        /// <param name = "queryParameterModel" ></ param >
        /// < returns ></ returns >
        public List<PickListModel> RetrievePicklistFromSpecified(string EntityName, string AttributeName)
        {
            SQLDBHELPER dbhelper = new SQLDBHELPER();
            List<PickListModel> result = new List<PickListModel>();
            try
            {
                Hashtable paras = new Hashtable();
                paras.Add("EntityName", EntityName);
                paras.Add("AttributeName", AttributeName);

                result = dbhelper.ExecStoredProcedureList<PickListModel>("p_cfp_GetAllEntityOptionSet", paras);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
            return result;
        }

        /// <summary>
        /// 根据条件获取数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="conditions">根据条件</param>
        /// <param name="_service">CRM服务</param>
        /// <param name="entityName">实体名称</param>
        /// <param name="pageNumber">当前页数</param>
        /// <param name="pageSize">页面大小</param>
        /// <returns></returns>
        public List<T> QueryDataByModel<T>(List<ConditionExpression> conditions, IOrganizationService _service, string entityName, int pageNumber, int pageSize)
        {
            var t = typeof(T);
            //得到要查询的字段
            IEnumerable<string> arrs = t.GetProperties().Where(w => !w.Name.EndsWith("Name")).Select(x => $"{x.Name.ToLower()}");
            //拼接字段
            string[] arrs1 = arrs.ToArray();

            EntityCollection entityList = GetEntities(_service, entityName, conditions, pageNumber, pageSize, arrs1);

            //得到实体集合
            var list = EntityToModel<T>(entityList);


            return (List<T>)list;
        }



        public EntityCollection GetEntities(IOrganizationService _CrmService, string entityname, List<ConditionExpression> conditions,
            int pageNumber, int pageSize, string[] columns = null, string sortKey = "createdon", OrderType sorttype = OrderType.Ascending)
        {
            List<Entity> entities = new List<Entity>();
            EntityCollection entitys = null;
            FilterExpression filter = new FilterExpression();
            filter.FilterOperator = LogicalOperator.And;

            if (conditions != null && conditions.Count > 0)
            {
                foreach (ConditionExpression con in conditions)
                {
                    filter.AddCondition(con);
                }
            }

            OrderExpression oe = new OrderExpression();
            oe.OrderType = sorttype;
            oe.AttributeName = sortKey;

            QueryExpression query = new QueryExpression();
            query.EntityName = entityname;
            if (columns != null)
            {
                query.ColumnSet = new ColumnSet(columns);
            }
            else
            {
                query.ColumnSet = new ColumnSet(true);
            }

            query.PageInfo = new PagingInfo() { Count = pageSize, ReturnTotalRecordCount = true, PageNumber = pageNumber };
            query.Criteria = filter;
            query.Orders.Add(oe);

            RetrieveMultipleRequest retrieve = new RetrieveMultipleRequest();
            retrieve.Query = query;
            //retrieve.ReturnDynamicEntities = true;
            try
            {
                RetrieveMultipleResponse retrieved = (RetrieveMultipleResponse)_CrmService.Execute(retrieve);
                entitys = retrieved.EntityCollection;
                //int num = retrieved.EntityCollection.Entities.Count;
                //if (num > 0)
                //{
                //    int i = 0;
                //    foreach (Entity ent in retrieved.EntityCollection.Entities.ToList())
                //    {
                //        entities.Add(ent);
                //        i++;
                //    }
                //}
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return entitys;
        }




        public EntityCollection GetEntities(IOrganizationService _CrmService, string entityname, List<FilterExpression> filters,
           int pageNumber, int pageSize, string[] columns = null, string sortKey = "createdon", OrderType sorttype = OrderType.Ascending)
        {
            List<Entity> entities = new List<Entity>();
            EntityCollection entitys = null;

            OrderExpression oe = new OrderExpression();
            oe.OrderType = sorttype;
            oe.AttributeName = sortKey;

            QueryExpression query = new QueryExpression();
            query.EntityName = entityname;
            if (columns != null)
            {
                query.ColumnSet = new ColumnSet(columns);
            }
            else
            {
                query.ColumnSet = new ColumnSet(true);
            }

            query.PageInfo = new PagingInfo() { Count = pageSize, ReturnTotalRecordCount = true, PageNumber = pageNumber };

            foreach (FilterExpression item in filters)
            {
                query.Criteria.AddFilter(item);
            }

            query.Orders.Add(oe);

            RetrieveMultipleRequest retrieve = new RetrieveMultipleRequest();
            retrieve.Query = query;
            //retrieve.ReturnDynamicEntities = true;
            try
            {
                RetrieveMultipleResponse retrieved = (RetrieveMultipleResponse)_CrmService.Execute(retrieve);
                entitys = retrieved.EntityCollection;
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return entitys;
        }


        public EntityCollection GetEntities(IOrganizationService _CrmService, string entityname, List<ConditionExpression> conditions,
            string[] columns = null, string sortKey = "createdon", OrderType sorttype = OrderType.Ascending)
        {
            List<Entity> entities = new List<Entity>();
            EntityCollection entitys = null;
            FilterExpression filter = new FilterExpression();
            filter.FilterOperator = LogicalOperator.And;

            if (conditions != null && conditions.Count > 0)
            {
                foreach (ConditionExpression con in conditions)
                {
                    filter.AddCondition(con);
                }
            }

            OrderExpression oe = new OrderExpression();
            oe.OrderType = sorttype;
            oe.AttributeName = sortKey;

            QueryExpression query = new QueryExpression();
            query.EntityName = entityname;
            if (columns != null)
            {
                query.ColumnSet = new ColumnSet(columns);
            }
            else
            {
                query.ColumnSet = new ColumnSet(true);
            }

            //query.PageInfo = new PagingInfo() { Count = pageSize, ReturnTotalRecordCount = true, PageNumber = pageNumber };
            query.Criteria = filter;
            query.Orders.Add(oe);

            RetrieveMultipleRequest retrieve = new RetrieveMultipleRequest();
            retrieve.Query = query;
            //retrieve.ReturnDynamicEntities = true;
            try
            {
                RetrieveMultipleResponse retrieved = (RetrieveMultipleResponse)_CrmService.Execute(retrieve);
                entitys = retrieved.EntityCollection;
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return entitys;
        }



        public EntityCollection GetEntitiesDescending(IOrganizationService _CrmService, string entityname, List<ConditionExpression> conditions,
            string[] columns = null, string sortKey = "createdon", OrderType sorttype = OrderType.Descending)
        {
            List<Entity> entities = new List<Entity>();
            EntityCollection entitys = null;
            FilterExpression filter = new FilterExpression();
            filter.FilterOperator = LogicalOperator.And;

            if (conditions != null && conditions.Count > 0)
            {
                foreach (ConditionExpression con in conditions)
                {
                    filter.AddCondition(con);
                }
            }

            OrderExpression oe = new OrderExpression();
            oe.OrderType = sorttype;
            oe.AttributeName = sortKey;

            QueryExpression query = new QueryExpression();
            query.EntityName = entityname;
            if (columns != null)
            {
                query.ColumnSet = new ColumnSet(columns);
            }
            else
            {
                query.ColumnSet = new ColumnSet(true);
            }

            //query.PageInfo = new PagingInfo() { Count = pageSize, ReturnTotalRecordCount = true, PageNumber = pageNumber };
            query.Criteria = filter;
            query.Orders.Add(oe);

            RetrieveMultipleRequest retrieve = new RetrieveMultipleRequest();
            retrieve.Query = query;
            //retrieve.ReturnDynamicEntities = true;
            try
            {
                RetrieveMultipleResponse retrieved = (RetrieveMultipleResponse)_CrmService.Execute(retrieve);
                entitys = retrieved.EntityCollection;
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return entitys;
        }
        public static Guid GetUserID(string UserName)
        {
            Guid UserId = Guid.Empty;
            SQLDBHELPER sql = new SQLDBHELPER();
            DataTable dt = sql.ExecuteDt(@"SELECT SystemUserId from systemuser WHERE SUBSTRING(DomainName,PATINDEX('%\%', DomainName) + 1,len(DomainName)) = '" + UserName + "'");
            if (dt != null && dt.Rows.Count == 1)
            {
                UserId = Guid.Parse(dt.Rows[0]["SystemUserId"].ToString());
            }
            return UserId;
        }
    }
}